package net.moonbiter.ebs.docs;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.util.Map;

import org.apache.log4j.Logger;

import net.moonbiter.ebs.InputDef;
import net.moonbiter.ebs.ServiceDef;
import net.moonbiter.ebs.ServiceProviderDef;
import net.moonbiter.ebs.ServicesRegister;
import net.moonbiter.ebs.descriptors.Descriptor;
import net.moonbiter.ebs.descriptors.InstantiatorDescriptor;
import net.moonbiter.ebs.descriptors.PropertiesDescriptor;

public class DocWriter {
	private static Logger logger = Logger.getLogger(DocWriter.class);

	public static void writeHtml(PrintWriter writer, String providerName,
			String serviceName, ServiceDef servDef) throws IOException {

		writer.println("<h1>" + providerName + "." + serviceName + "</h1>");

		Map<String, InputDef> inputs = servDef.getInputs();
		writer.println("<i>" + inputs.keySet().size() + " inputs</i>");

		int index = 0;
		for (String inputName : inputs.keySet()) {
			showHtmlInputDefDoc(writer, index, inputName, inputs.get(inputName));
		}

		writer.close();
	}
	
	public static void writeText(PrintWriter writer, ServicesRegister servReg) throws IOException {
		logger.debug("Going to write text for a Service Register with "
				+servReg.getProvidersNb()+" service providers");
		for (String providerName : servReg.getProvidersNames()){
			logger.debug("Writing text for provider "+providerName);
			ServiceProviderDef provider = servReg.getProvider(providerName);
			for (String serviceName : provider.getServicesNames()){
				logger.debug("Writing text for service "+providerName+"."+serviceName);
				ServiceDef serv = provider.getService(serviceName);
				writeText(writer, providerName, serviceName, serv);
			}
		}
	}
	
	public static void writeText(PrintWriter writer, String providerName,
			String serviceName, ServiceDef servDef) throws IOException {
		logger.debug("Writing text for "+providerName+"."+serviceName);
		writer.println("---" + providerName + "." + serviceName + "---");

		Map<String, InputDef> inputs = servDef.getInputs();
		writer.println("(" + inputs.keySet().size() + ")");

		int index = 0;
		for (String inputName : inputs.keySet()) {
			showTextInputDefDoc(writer, index, inputName, inputs.get(inputName));
		}
	}	

	private static void showHtmlInputDefDoc(PrintWriter writer, int index,
			String inputName, InputDef inputDef) {
		writer.println("<h3>Param " + (index + 1) + ") " + inputName + "<h3>");
		writer.println("&nbsp;&nbsp;&nbsp;java class: "
				+ inputDef.getType().getCanonicalName() + ", <i>optional? "
				+ inputDef.isOptional() + "</i>");
	}

	private static void showTextInputDefDoc(PrintWriter writer, int index,
			String inputName, InputDef inputDef) {
		writer.println("- Param " + (index + 1) + ") " + inputName);
		writer.println("\tjava class: " + inputDef.getType().getCanonicalName()
				+ ", (optional? " + inputDef.isOptional() + ")");
		if (inputDef.hasSpecificDescriptor()) {
			writer.println("\tdescriptor:");
			showTextDescriptor(writer, inputDef.getSpecificDescriptor());
		}
	}

	private static void showTextDescriptor(PrintWriter writer,
			Descriptor<?, ?> descriptor) {
		if (descriptor instanceof DescriptorWriter) {
			DescriptorWriter descriptorWriter = (DescriptorWriter)descriptor;
			writer.print(descriptorWriter.write());
		} else {
			writer
					.println("\t\tI don't know how to describe the descriptor...");
		}
	}
	
}
